#include "stdafx.h"
#include "String.h"

#include <string>
using namespace std;

String::String()
{
  this->_size = 0;
  this->_cadena = NULL;
}

String::String ( const String& str )
{
  this->_cadena = new char[str.size()];
  this->_size = str.size();

  size_t j;
  for ( j=0; j<str.size(); j++ )
  {
    this->_cadena[j] = str[j];
  }

}

String::String ( const char * s , size_t size )
{
  this->_size = size;
  this->_cadena = new char[size];

  size_t j;
  for ( j=0; j<size; j++ )
  {
    this->_cadena[j] = s[j];
  }

}

String::String ( const char * s )
{
  string str( s );
  this->_cadena = new char[str.size()];
  this->_size = str.size();
  size_t j;
  for ( j=0; j<this->_size; j++ )
  {
    this->_cadena[j] = str[j];
  }
}

String::String( const string& cadena )
{
  this->_size = cadena.size();
  this->_cadena = new char[cadena.size()];

  size_t j;
  for ( j=0; j<this->_size; j++ )
  {
    this->_cadena[j] = cadena[j];
  }

}

char* String::toChar()
{
    return this->_cadena;
}

size_t String::size()const
{
  return this->_size;
}

void String::resize ( size_t n, char c )
{
  if (n>this->_size)
  {
    string strRelleno;
    strRelleno.resize( n-this->_size, c );
    String str( strRelleno );
    (*this)+=str;
  }
  else if (n<this->_size)
  {
    char* strResto;
    strResto = new char[n];

    size_t j;
    for (j=0; j<n; j++)
    {
      strResto[j] = this->_cadena[j];
    }
    delete []this->_cadena;
    this->_cadena = strResto;
  }
}


String& String::operator= ( const String& str )
{
  if ( &str != this )
  {
    if ( this->_cadena )
    {
      delete []this->_cadena;
    }
    this->_cadena = new char[str.size()];
    this->_size = str.size();

    size_t j;
    for ( j=0; j<str.size(); j++ )
    {
      this->_cadena[j] = str[j];
    }

  }
  return *this;
}

String& String::operator= ( const string& str )
{


    if ( this->_cadena )
    {
      delete []this->_cadena;
    }
    this->_cadena = new char[str.size()];
    this->_size = str.size();

    size_t j;
    for ( j=0; j<str.size(); j++ )
    {
      this->_cadena[j] = str[j];
    }


  return *this;
}

String& String::operator= ( char c )
{
  if ( this->_cadena )
  {
    delete []this->_cadena;
  }
  this->_size = 1;
  this->_cadena = new char[1];
  this->_cadena[0] = c;
  return *this;
}

String& String::operator= ( const char* s )
{
  delete[] this->_cadena;
  this->_size = 0;
  if (s)
  {
    size_t j;
    string str( s );
    this->_size = str.size();
    this->_cadena = new char[this->_size];

    for (j = 0; j<this->_size; j++)
    {
      this->_cadena[j] = s[j];
    }
  }
  return (*this);
}

String& String::operator+= ( const String& str )
{
  char* cadena = this->_cadena;
  this->_cadena = new char[this->_size + str.size()];
  size_t j;

  if ( cadena )
  {
    for (j = 0; j<this->_size; j++)
    {
      this->_cadena[j] = cadena[j];
    }
    delete []cadena;
  }

  for (j = 0; j<str.size(); j++)
  {
    this->_cadena[j+this->_size] = str[j];
  }

  this->_size += str.size();
  return *this;
}

String& String::operator+= ( char c )
{
  char* cadena = this->_cadena;
  this->_cadena = new char[this->_size + 1];

  if (cadena)
  {
    size_t j;
    for (j = 0; j<this->_size; j++)
    {
      this->_cadena[j] = cadena[j];
    }
    delete []cadena;
  }

  this->_size += 1;
  this->_cadena[this->_size-1] = c;

  return *this;
}

bool String::operator== ( const String& str )
{
  bool iguales = (this->_size = str.size());
  if ( iguales )
  {
    size_t j=0;
    while ( (j<this->_size) && (iguales) )
    {
      iguales = ( (*this)[j] == str[j] );
      j++;
    }
  }
  return iguales;

}

int String::comparar( const String& str )
{
    bool iguales = true;
    size_t j=0;
    while (iguales) {

        iguales = ( (*this)[j] == str[j] );
        if (!iguales){
            if ( (*this)[j] > str[j]){
                return 1;
            } else {
                return -1;
            }
        }
        j++;
        bool finThis = false, finStr = false;

        if (j >= this->size())
            finThis = true;
        if (j >= str.size())
            finStr = true;

        if ((finThis == true) && (finStr== true)) {
            return 0;
        } else {
            if (finThis == true) {
                return -1;
             } else {
                if (finStr == true)
                    return 1;
             }
        }
    }
    return 0;
}

String String::substr ( size_t pos , size_t n  ) const
{
  if ( (this->_cadena) && (pos < this->_size) )
  {
    if ( (n+pos)>this->_size ) n = this->_size-pos;
    String str( this->_cadena+(sizeof(char)*pos), n );
    return str;
  }
  String str;
  return str;
}

string String::tostring( size_t size )
{
  string str( this->_cadena, size );
  return str;
}

string String::tostring()
{
  string str( this->_cadena);
  return str;
}

const char& String::operator[] ( size_t pos ) const
{
  return this->_cadena[pos];
}

char& String::operator[] ( size_t pos )
{
  return this->_cadena[pos];
}

String::~String()
{
  if (this->_cadena)
  {
    delete []this->_cadena;
  }
}

ostream& operator<< ( ostream& stream, const String& cadena )
{
  size_t j;
  for ( j=0; j<cadena.size(); j++ )
  {
    stream << cadena[j];
  }
  return stream;
}

bool String::read( istream& stream, size_t size )
{
  if ( this->_cadena )
  {
    delete [] this->_cadena;
    this->_size = 0;
  }

  char* buff = new char[size];
  size_t leidos = 0;
  while ( (!stream.eof()) && (leidos < size) )
  {
    stream.read( &(buff[leidos]), 1 );
    leidos++;
  }

  this->_size = leidos;
  this->_cadena = new char[ this->_size ];

  for ( leidos=0; leidos < this->_size; leidos++ )
  {
    this->_cadena[leidos] = buff[leidos];
  }

  delete[] buff;
  return ( leidos == size );

}
